package com.quectel.sys.module.sys.service.impl;


import cn.hutool.core.lang.func.LambdaUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.quectel.constant.global.SystemConstants;
import com.quectel.constant.sys.SysConstants;
import com.quectel.sys.module.sys.dao.SysTenantDao;
import com.quectel.sys.module.sys.dto.SysGroupDto;
import com.quectel.sys.module.sys.dto.SysRoleDto;
import com.quectel.sys.module.sys.dto.SysTenantDto;
import com.quectel.sys.module.sys.dto.SysUserDto;
import com.quectel.sys.module.sys.entity.SysTenantEntity;
import com.quectel.sys.module.sys.service.SysGroupService;
import com.quectel.sys.module.sys.service.SysRoleService;
import com.quectel.sys.module.sys.service.SysTenantService;
import com.quectel.sys.module.sys.service.SysUserService;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.kit.Snowflake;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author rananxin
 * @date 2021-09-01 09:31:45
 */
@DubboService
public class SysTenantServiceImpl implements SysTenantService {

    private static final Logger LOGGER = LoggerFactory.getLogger(SysTenantServiceImpl.class);

    @Autowired
    private SysTenantDao sysTenantDao;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysGroupService sysGroupService;
    @Autowired
    private SysRoleService sysRoleService;


    @Override
    public SysTenantDto selectOneByCode(String code) {
        SysTenantEntity sysTenantEntity = sysTenantDao.selectOne(new LambdaQueryWrapper<SysTenantEntity>().eq(SysTenantEntity::getCode, code));
        return CopyUtils.copyObj(sysTenantEntity, SysTenantDto.class);
    }

    @Override
    public List<SysTenantDto> queryList(Map<String, Object> params) {
        List<SysTenantEntity> list = sysTenantDao.queryList(params);
        List<SysTenantDto> sysTenantDtos = CopyUtils.copyList(list, SysTenantDto.class);

        for (SysTenantDto sysTenantDto : sysTenantDtos) {
            SysUserDto sysUserDto = sysUserService.getAdminByTenantId(sysTenantDto.getId(), true);
            Integer count = sysUserService.queryTotal(new HashMap<String, Object>() {{
                put("tenantId", sysTenantDto.getId());
            }});

            sysTenantDto.setAdminUser(sysUserDto);
            sysTenantDto.setSysUserCount(count);
        }
        return sysTenantDtos;
    }

    @Override
    public int queryTotal(Map<String, Object> params) {
        return sysTenantDao.queryTotal(params);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long save(SysTenantDto sysTenantDto, SysUserDto sysUserDto) {
        Date currentDate = new Date();

        SysTenantEntity entity = CopyUtils.copyObj(sysTenantDto, SysTenantEntity.class);
        entity.setId(Snowflake.nextId());
        sysTenantDao.insert(entity);
        Long cTenantId = entity.getId();

        SysTenantDto sysTopTenant = selectOneByCode(SysConstants.SYS_TOP_TENANT_CODE);
        SysUserDto sysTopUser = sysUserService.getAdminByTenantId(sysTopTenant.getId(), false);

        SysGroupDto sysGroupDto = new SysGroupDto();
        sysGroupDto.setTenantId(cTenantId);
        sysGroupDto.setCode(SysConstants.SYS_TOP_GROUP_CODE);
        sysGroupDto.setName(SysConstants.SYS_TOP_GROUP_NAME);
        sysGroupDto.setParentId(SystemConstants.TREE_DEFAULT_PARENT_ID);
        sysGroupDto.setLevel(SystemConstants.TREE_DEFAULT_LEVEL);
        sysGroupDto.setSort(SystemConstants.DEFAULT_SORT);
        sysGroupDto.setOpen(true);
        sysGroupDto.setStatus(SystemConstants.NORMAL);
        sysGroupDto.setAuthorityType(SysConstants.GroupAuthEnum.BY_VILLAGE.getType());
        sysGroupDto.setIsPartyManager(SystemConstants.YES);
        sysGroupDto.setCreator(sysTopUser.getAccount());
        sysGroupDto.setCreateTime(currentDate);
        Long cGroupId = sysGroupService.save(sysGroupDto);

        sysUserDto.setStatus(SystemConstants.YES);
        sysUserDto.setGroupId(cGroupId);
        sysUserDto.setTenantId(cTenantId);
        sysUserDto.setCreator(sysTopUser.getAccount());
        sysUserDto.setCreateTime(currentDate);
        sysUserDto.setIsTenantAdmin(SystemConstants.YES);
        sysUserService.save(sysUserDto);

        return cTenantId;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateById(SysTenantDto sysTenantDto, SysUserDto sysUserDto) {
        SysTenantEntity entity = CopyUtils.copyObj(sysTenantDto, SysTenantEntity.class);
        sysTenantDao.updateById(entity);

        SysUserDto dto = new SysUserDto();
        dto.setId(sysUserDto.getId());
        dto.setUsername(sysUserDto.getUsername());
        dto.setMobile(sysUserDto.getMobile());
        dto.setEmail(sysUserDto.getEmail());
        dto.setEditTime(new Date());
        dto.setUserRoleList(sysUserDto.getUserRoleList());
        sysUserService.updateById(dto);
    }

    @Override
    public SysTenantDto selectById(Long id) {
        SysTenantEntity entity = sysTenantDao.selectById(id);
        SysTenantDto sysTenantDto = CopyUtils.copyObj(entity, SysTenantDto.class);
        if (sysTenantDto != null) {
            SysUserDto sysUserDto = sysUserService.getAdminByTenantId(sysTenantDto.getId(), false);
            sysTenantDto.setAdminUser(sysUserDto);
        }
        return sysTenantDto;
    }

    @Override
    public void deleteById(Long id) {
        sysTenantDao.deleteById(id);

        //删除角色
        HashMap<String, Object> hashMap = Maps.newHashMap();
        hashMap.put(LambdaUtil.getFieldName(SysRoleDto::getTenantId), id);
        List<SysRoleDto> sysRoleDtos = sysRoleService.queryList(hashMap);
        if (sysRoleDtos != null && sysRoleDtos.size() > 0) {
            Long[] roleIds = sysRoleDtos.stream().map(SysRoleDto::getId).toArray(Long[]::new);
            sysRoleService.deleteBatch(roleIds);
        }

        //删除所有用户
        SysGroupDto sysGroupDto = sysGroupService.selectByCode(SysConstants.SYS_TOP_GROUP_CODE, (Long) id);
        if (sysGroupDto == null) {
            return;
        }
        List<SysUserDto> subUsers = sysGroupService.getSubUsers(sysGroupDto.getId());
        if (subUsers != null && subUsers.size() > 0) {
            Long[] userIds = subUsers.stream().map(SysUserDto::getId).toArray(Long[]::new);
            sysUserService.deleteBatch(userIds);
        }
        //删除下级组
        List<SysGroupDto> sysGroupDtos = sysGroupService.selectByParentId(sysGroupDto.getId());
        sysGroupDtos.add(sysGroupDto);
        Long[] groupIds = sysGroupDtos.stream().map(SysGroupDto::getId).toArray(Long[]::new);
        sysGroupService.deleteBatch(groupIds);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(Long[] ids) {
        for (Long id : ids) {
            deleteById(id);
        }
    }
}
